require("mason").setup()
require("mason-lspconfig").setup({
    handlers = {

        function (server_name) -- default handler (optional)
            require("lspconfig")[server_name].setup {}
        end,

        ["lua_ls"] = function ()
            local lspconfig = require("lspconfig")
            lspconfig.lua_ls.setup {
                Lua = {
                    diagnostics = {
                        globals = { "vim" }
                    }
                }
            }
        end
    }
})

--
-- require("lspconfig").intelephense.setup {}
-- require("lspconfig").lua_ls.setup {}
-- require("lspconfig").vimls.setup {}

local capabilities = require('cmp_nvim_lsp').default_capabilities()

local lsp_servers = { 'intelephense', 'vimls', 'jsonls', 'cssls', 'html', 'cssmodules_ls', 'tailwindcss', 'vuels' }
for _, server in ipairs(lsp_servers) do
    require('lspconfig')[server].setup {
        capabilities = capabilities
    }
end

-- diagnostics --
local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " }
for type, icon in pairs(signs) do
    local hl = "DiagnosticSign" .. type
    vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end



-- Global mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist)

-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd('LspAttach', {
    group = vim.api.nvim_create_augroup('UserLspConfig', {}),
    callback = function(ev)
        -- Enable completion triggered by <c-x><c-o>
        vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'

        -- Buffer local mappings.
        -- See `:help vim.lsp.*` for documentation on any of the below functions
        local opts = {
            buffer = ev.buf
        }
        vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
        vim.keymap.set('n', 'gd', '<cmd>Telescope lsp_definitions<CR>', opts)
        vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
        opts.desc = "Show LSP type definitions"
        vim.keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts) -- show lsp type definitions
        opts.desc = "Show LSP implementations"
        vim.keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts)  -- show lsp implementations
        vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
        vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
        vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
        vim.keymap.set('n', '<space>wl', function()
            print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
        end, opts)
        vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
        vim.keymap.set('n', '<space>o', "<cmd>Telescope lsp_document_symbols<CR>", opts)
        vim.keymap.set('n', '<space>O', "<cmd>Telescope lsp_workspace_symbols<CR>", opts)
        vim.keymap.set('n', '<leader>ic', "<cmd>Telescope lsp_incoming_calls<CR>", {})
        vim.keymap.set('n', '<leader>oc', "<cmd>Telescope lsp_outgoing<CR>", {})
        vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename, opts)
        vim.keymap.set({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action, opts)
        opts.desc = "Show LSP references"
        vim.keymap.set("n", "gr", "<cmd>Telescope lsp_references<CR>", opts) -- show definition, references
        vim.keymap.set('n', '<space>f', function()
            vim.lsp.buf.format {
                async = true
            }
        end, opts)
    end
})
